package gamesrv.server.impl;

import java.util.*;

import org.osgi.framework.*;

import gamesrv.api.*;
import gamesrv.gameprovider.api.GameLogic;
import gamesrv.gameprovider.api.GameProvider;

public class GameServerImpl implements GameServer, ServiceListener,GameServerImplMXBean {

	HashMap<String,GameProvider> providers;
	HashMap<String,ArrayList<GameHandleImpl>> waitingHandles;
	ArrayList<GameContainer> runningGames;
	BundleContext context;
	
	
	
	
	public GameServerImpl(BundleContext context)
	{
		providers = new HashMap<String,GameProvider>();
		waitingHandles = new HashMap<String,ArrayList<GameHandleImpl>>();
		runningGames = new ArrayList<GameContainer>();
		this.context = context;
		 
		context.addServiceListener(this);
	}
	
	public List<String> getGameTypes() {
		List<String> types = new ArrayList<String>();		
		
		for (Iterator<String> e = providers.keySet().iterator(); e.hasNext();) 
		{
			types.add(e.next());
		}		
		return types;
	}

	public synchronized  GameHandle startGame(String type,String userName) {
		ArrayList<GameHandleImpl> otherWaiting =  waitingHandles.get(type);
		
		if (otherWaiting == null)
		{
			otherWaiting = new ArrayList<GameHandleImpl>();
			waitingHandles.put(type, otherWaiting);
		}
		
		GameHandleImpl handle = new GameHandleImpl(userName);
		otherWaiting.add(handle);
		
		if (otherWaiting.size() == providers.get(type).getGameUserCount())
		{
			waitingHandles.remove(type);
			GameLogic game = providers.get(type).createGame();			
			
			GameContainer container = new GameContainer(game,type,otherWaiting,context);
			runningGames.add(container);
		}
		
		return handle;						
	}

	
	public void serviceChanged(ServiceEvent arg0) {
		ServiceReference<?> sr = arg0.getServiceReference();		
		String cls = ((String[])sr.getProperty("objectclass"))[0];
		
		if (cls ==   GameProvider.class.getName() )
		{
			if (arg0.getType() == ServiceEvent.REGISTERED)
			{				
				GameProvider provider = (GameProvider) context.getService(sr);
				this.providers.put(provider.getGameType(),provider);
				System.out.println("Game service: found new game provider: " + provider.getGameType());
			}
			if (arg0.getType() == ServiceEvent.UNREGISTERING)
			{
				
			}
		}		
		
	}

	
	public List<GameInfo> getRunningGames() {
		ArrayList<GameInfo> infos = new ArrayList<GameInfo>();
		for (int i=0; i < runningGames.size(); i++)
			infos.add(new GameInfo(runningGames.get(i)));
		return infos;
	}

}
